<?php
/**
 *  当数据完全是从第三方获取时，使用
 *  三级数据数据获取机制
 *  1、cache
 *  2、db
 *  3、base类的数据获取方式
 *  存储方式
 *  提供失效机制 kv timeout
 */

class dc_apiBase extends apiBase {
    
    function __construct() {
        $this->_db = vApi::DB();
        $this->_table_name = API_TB_KV;
        $this->_table = $this->_db->getTable($this->_table_name);
        $this->_key_prefix = 'wow';
    }
    /**
     *  三步尝试获取数据
     */
    
    function cdb($callable, $args,$timeout = 0) {
        $this->_cache = vApi::getBase('apiCache');
        //return call_user_func_array($callable,$args?$args:array());
        $cache_key = md5(serialize($callable) . serialize($args).$this->_key_prefix);
        if (!($rst = $this->_cache->get('kv',$cache_key))) {
            $sql = $this->_db->SQL("SELECT `value`,`timeout` FROM %s WHERE `key`='%s';", $this->_table, $cache_key);
            $time = time();
            $over_time = FALSE; //是否超时
            if (!($rst = $this->_db->getRow($sql)) || ($rst['timeout'] < $time && $over_time = TRUE)) {
                if (!($rst = call_user_func_array($callable,$args?$args:array()))) {
                    return NULL;
                }
                $this->_cache->set('kv',$cache_key, $rst, $timeout);
                $this->_db->save(array(
                    'value' => json_encode($rst) ,
                    'timeout' => $time + $timeout,
                    'key' => $cache_key
                ) , $over_time ? $cache_key : NULL, $this->_table_name,'key');
            }
            else {
                $rst = json_decode($rst['value'], TRUE);
                //set cache
                $this->_cache->set('kv',$cache_key, $rst, $timeout);
            }
        }
        return $rst;
    }
    /**
      *  1、database
      *  2、base call
      */
    function db($callable, $args,$timeout = 0){
        $cache_key = md5(serialize($callable) . serialize($args).$this->_key_prefix);
        $sql = $this->_db->SQL("SELECT `value`,`timeout` FROM %s WHERE `key`='%s';", $this->_table, $cache_key);
        $time = time();
        $over_time = FALSE; //是否超时
        if (!($rst = $this->_db->getRow($sql)) || ($rst['timeout'] < $time && $over_time = TRUE)) {
            if (!($rst = call_user_func_array($callable,$args?$args:array()))) {
                return NULL;
            }
            $this->_db->save(array(
                'value' => json_encode($rst) ,
                'timeout' => $time + $timeout,
                'key' => $cache_key
            ) , $over_time ? $cache_key : NULL, $this->_table_name,'key');
        }
        else {
            $rst = json_decode($rst['value'], TRUE);
        }
        return $rst;
    }
    
    /**
      *  根据常量判断使用上述哪个方法 
      */
    function get($callable, $args,$timeout = 0){
        if(SUPPORT_DATA_CACHE){
            return call_user_func_array(array($this,'cdb'),func_get_args());
        }
        else{
            return call_user_func_array(array($this,'db'),func_get_args());
        }
        
        
    }
}
?>